﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LINQ_EXC
{
    class Group
    {
        public Group(int GroupNumber, string DepartmentName)
        {
            this.DepartmentName = DepartmentName;
            this.GroupNumber = GroupNumber;
        }

        public string DepartmentName { get; set; }
        public int GroupNumber { get; set; }
    }

    class Student
    {

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public int FN { get; set; }
        public int GroupNumber { get; set; }
        public List<int> Marks { get; set; }

        public Student(string FirstName, string lastName, string email, int fn, int groupNumber)
        {
            this.Email = email;
            this.FirstName = FirstName;
            this.FN = fn;
            this.GroupNumber = groupNumber;
            this.LastName = lastName;
            this.Marks = new List<int>();
        }

        public override string ToString()
        {
            return string.Format("{0} {1}, e-mail: {2}, fn: {3}, gr: {4}", this.FirstName, this.LastName, this.Email, this.FN, this.GroupNumber);
        }

        public string MarksToString()
        {
            StringBuilder str = new StringBuilder();
            foreach (var mark in Marks)
            {
                str.Append(mark);
                str.Append(" ");
            }
            str.Remove(str.Length - 2, 1);
            return str.ToString();
        }
    }

    class TestProgram
    {

        public static void Ex1()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("awdwad", "awdwad", "awdawd", 23323, 1));
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("awdawd", "awdawd", "awdawdwad", 23423, 3));
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studentsFromGroup2 =
                from s in students
                where s.GroupNumber == 2
                select s;
            foreach (var stud in studentsFromGroup2)
            {
                Console.WriteLine(stud);
            }
        }

        public static void Ex2()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("awdwad", "awdwad", "awdawd", 23323, 1));
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("awdawd", "awdawd", "awdawdwad", 23423, 3));
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studentsFromGroup2 = students.FindAll(obj => obj.GroupNumber == 2);
            foreach (var stud in studentsFromGroup2)
            {
                Console.WriteLine(stud);
            }
        }

        public static void Ex3()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosh", "awdwad", "awdw@abv.bg", 23323, 1));
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studentsFromGroup2 = students.FindAll(obj => obj.Email.EndsWith("abv.bg"));
            foreach (var stud in studentsFromGroup2)
            {
                Console.WriteLine(stud);
            }
        }

        public static void Ex4()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosh", "awdwad", "awdw@abv.bg", 23323, 1));
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studentsFromGroup2 = students.FindAll(student => Regex.IsMatch(student.Email, @"(\w|\.|@)*abv.bg") == true);
            foreach (var stud in studentsFromGroup2)
            {
                Console.WriteLine(stud);
            }
        }

        public static void Ex5()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosho", "awdwad", "gosha@abv.bg", 23323, 1));
            students[0].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students[2].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studentsFromGroup2 =
                from s in students
                where s.Marks.Contains(6)
                select new { FullName = s.FirstName + " " + s.LastName, Marks = s.MarksToString() };
            foreach (var stud in studentsFromGroup2)
            {
                Console.WriteLine(stud.FullName + " " + stud.Marks);
            }
        }

        public static void Ex6()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosho", "awdwad", "gosha@abv.bg", 23323, 1));
            students[0].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students[2].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 2, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));

            var studs = students.FindAll(stud => stud.Marks.Count(el => el == 2) == 2)
                .Select(stud => new
                {
                    FullName = stud.FirstName + " " + stud.LastName,
                    Marks = stud.MarksToString()
                });

            foreach (var stud in studs)
            {
                Console.WriteLine(stud.FullName + " " + stud.Marks);
            }
        }

        public static void Ex8()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosho", "awdwad", "gosha@abv.bg", 23323, 1));
            students[0].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students[2].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 2, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 2));
            List<Group> groups = new List<Group>();
            groups.Add(new Group(1, "MAT"));
            groups.Add(new Group(2, "MAT"));
            groups.Add(new Group(3, "MAT"));
            groups.Add(new Group(2, "ANA"));

            //var studs = students.Join(groups,
            //    student => student.GroupNumber,
            //    group => group.GroupNumber,
            //    (student, group) => new {
            //            Name = student.FirstName, Department = group.DepartmentName })
            //    .Where(obj => obj.Department.Equals("MAT"));

            var studs =
                from st in students
                join g in groups
                on st.GroupNumber equals g.GroupNumber
                where g.DepartmentName.Equals("MAT")
                select new
                {
                    Name = st.FirstName,
                    Department = g.DepartmentName
                };
            foreach (var stud in studs)
            {
                Console.WriteLine(stud.Name + " " + stud.Department);
            }
        }

        public static void Ex9()
        {
            string text = @"awdpoawld ow kdaowkdawo dkaw odkaw odkadawaod ";
            string[] strings = text.Split(' ');

            decimal len = strings.Max(str => str.Length);
            Console.WriteLine(strings.FirstOrDefault(obj => obj.Length == len));
        }

        public static void Ex10()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosho", "awdwad", "gosha@abv.bg", 23323, 1));
            students[0].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students[2].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 2, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 3));
            List<Group> groups = new List<Group>();
            groups.Add(new Group(1, "ANA"));
            groups.Add(new Group(2, "MAT"));
            groups.Add(new Group(3, "ASA"));

            var studs =
                from st in students
                join g in groups
                on st.GroupNumber equals g.GroupNumber
                group st by g.DepartmentName;

            foreach (var town in studs)
            {
                Console.Write("Dep {0}: ", town.Key);
                foreach (var person in town)
                    Console.Write("{0} {1}, ", person.FirstName, person.LastName);
                Console.WriteLine();
            }
        }

        public static void Ex11()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("gosho", "awdwad", "gosha@abv.bg", 23323, 1));
            students[0].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdwad", "awdwad", 23343, 2));
            students.Add(new Student("ivan", "awdawd", "ivan@abv.bg", 23423, 3));
            students[2].Marks = new List<int>(new int[] { 2, 3, 4, 5, 7645, 65, 44, 5, 2, 6, 7, 7 });
            students.Add(new Student("awdawd", "awdawd", "awdwad", 23423, 3));
            List<Group> groups = new List<Group>();
            groups.Add(new Group(1, "ANA"));
            groups.Add(new Group(2, "MAT"));
            groups.Add(new Group(3, "ASA"));

            var studs = students.Join(groups,
                student => student.GroupNumber,
                group => group.GroupNumber,
                (student, group) => new
                {
                    Name = student.FirstName,
                    Department = group.DepartmentName
                }).GroupBy(obj => obj.Department);

            foreach (var town in studs)
            {
                Console.Write("Dep {0}: ", town.Key);
                foreach (var person in town)
                    Console.Write("{0}, ", person.Name);
                Console.WriteLine();
            }
        }

        static void Main(string[] args)
        {
            //Ex1();
            //Ex2();
            //Ex3();
            //Ex4();
            //Ex5();
            //Ex6();
            //Ex8();
            //Ex9();
            Ex10();
            Console.WriteLine();
            Ex11();
        }
    }
}
